#pragma once

#include <stdarg.h>
#include <stdio.h>
#ifndef _WIN32
#include <termios.h>
#endif
#include <list>

#define LL_EMERG     0
#define LL_FATAL     0
#define LL_ALERT     1
#define LL_CRIT      2
#define LL_ERROR     3
#define LL_WARN      4
#define LL_NOTICE    5
#define LL_INFO      6
#define LL_DEBUG     7
#define LL_NOTSET    8

#define IN_LENGTH_MAX   256
#define HISTRORY_MAX    8

namespace host {

    class TestUnit
    {
    public:
        TestUnit(const char *name, const char *usage, int argnum);
        virtual ~TestUnit() {};
        virtual int TestUnitProc(const char* args[], int argc) = 0;

    public:
        const char* m_strName;
        int         m_nArgnum;
        const char* m_strUsage;
    }; 

    typedef struct {
        char        lines[128]; /* User printable name of the function. */
        char        name[64];   /* User printable name of the function. */
        int         argc;       /* Number of arguments that the function accepts. */
        char        args[16][64];   /* Documentation for this function.  */
        TestUnit*   unit;        /* Function to call to do the job. */
    } command_t;

    class OSCon
    {
        enum
        {
            DIRECTION_LEFT = 0,
            DIRECTION_RIGHT,
            DIRECTION_UP,
            DIRECTION_DOWN,
        };

    public:
        static void Print(const char *fmt, ...);
        static void PrintW(const char *fmt, ...);
        static void PrintG(const char *fmt, ...);
        static void PrintY(const char *fmt, ...);
        static void PrintR(const char *fmt, ...);

        static void BGLog(int level, const char* fmt, ...);
        static void LogV(int level, const char *fmt, ...);

        static void Init();
        static void Exit();

        OSCon();
        ~OSCon();
        void Run(const char *prompt);

        bool Execute(const char* lines);
        bool Execute(const char* lines[]);

    private:
        bool PaserLine(bool record = true);
        bool RunCmd(command_t* newCmd);

    private:
        char    m_cmdLine[IN_LENGTH_MAX];

    };

#define BGLog(level, fmt, ...) OSCon::LogV(level, fmt, ##__VA_ARGS__)
};
